#include "StdAfx.h"
#include "..\include\Line.h"

using namespace Common;

////////////////////////////////////////////////////////////Line2D////////////////////////////////////////////////////////////
////////////////////

/**
 *	Line-segment constructor
 */
inline Line2D::Line2D( const Vector2& v0, const Vector2& v1 )
{
	m_vNormal.x = v0.y - v1.y;
	m_vNormal.y = v1.x - v0.x;
	
	m_vNormal.normalise();

	m_fDistance = m_vNormal.dotProduct( v0 );
}



/**
 *	This method intersects this line with the other, returning the
 *	distance along the line that the intersection occurs.
 */
float Line2D::intersect( const Line2D & other ) const
{
	const Vector2 & on = other.m_vNormal;
	return (other.m_fDistance - m_fDistance * on.dotProduct( m_vNormal ) ) / on.crossProduct( m_vNormal );
}


/**
 *	Return the point that corresponds tot he given parameter
 */
Vector2 Line2D::param( float t ) const
{
	return Vector2(
		m_vNormal.x * m_fDistance + m_vNormal.y * t,
		m_vNormal.y * m_fDistance - m_vNormal.x * t );
}


/**
 *	Return the parameter of the given point projected onto the line
 */
float Line2D::project( const Vector2& point ) const
{
	Vector2 dir( m_vNormal.y, -m_vNormal.x );	// also unit length
	return dir.dotProduct( point - m_vNormal * m_fDistance );
}


/**
 *	Returns whether or not the given line is a minimum cutter of our line.
 *
 *	A minimum cutter means that if the intersection is greater than the
 *	minimum, this intersection forms the new minimum.
 */
bool Line2D::isMinCutter( const Line2D & cutter ) const
{
	return m_vNormal.crossProduct( cutter.m_vNormal ) > 0.f;
}


/**
 *	Returns whether or not this line is parallel with the other
 */
bool Line2D::isParallel( const Line2D & other ) const
{
	return fabs( m_vNormal.crossProduct( other.m_vNormal ) ) < 0.001f;
}


/**
 *	Returns whether or not the given point is in front of the line
 */
bool Line2D::isInFrontOf( const Vector2 & point ) const
{
	return m_vNormal.dotProduct( point ) > m_fDistance;
}












////////////////////////////////////////////////////////////Line3D////////////////////////////////////////////////////////////
////////////////////
Line3D::Line3D( const Vector3& point1, const Vector3& point2 )
{
	m_vOriPoint = point1;
	m_vDirection = point2 - point1;
}

Line3D::~Line3D(void)
{
}

float Line3D::DistanceToPoint( const Common::Vector3& point ) const
{
	//or we can make a plane by normal and vDirection, then get the distance from point to the plane.
	Vector3 cp = m_vDirection.crossProduct( m_vOriPoint - point );
	return cp.length() / m_vDirection.length();
}

bool Line3D::IsValid( void ) const
{
	return m_vDirection.length() == 0;
}
